<?php

namespace App\Repositories;

use App\Models\Bookmark;
use App\Repositories\RepositoryInterface;
use App\Repositories\EloquentRepository;
use App\Exceptions\Bookmark\CreateBookmarkErrorException;
use App\Exceptions\Bookmark\BookmarkNotFoundException;
use App\Exceptions\Bookmark\UpdateBookmarkErrorException;
use Illuminate\Database\QueryException;
use Illuminate\Database\Eloquent\ModelNotFoundException;

/**
 * A repository implementation with Eloquent ORM
 */
class BookmarkRepository extends EloquentRepository
{
    /**
     * @var Bookmark
     */
    protected $model;

    /**
     * @param Bookmark $bookmark
     */
    public function __construct(Bookmark $bookmark)
    {
        $this->model = $bookmark;
    }

    /**
     *  Create a new Bookmark.
     *
     * @param array $attributes
     *
     * @return Bookmark
     * @throws CreateBookmarkErrorException
     */
    public function create(array $attributes)
    {
        try {
            return $this->model->create($attributes);
        } catch (QueryException $e) {
            throw new CreateBookmarkErrorException("Can't create a Bookmark", 400);
        }
    }

    /**
     * Find a Bookmark.
     *
     * @param int $id
     *
     * @return Bookmark
     * @throws NotFoundBookmarkException
     */
    public function find(int $id)
    {
        try {
            return $this->model->findOrFail($id);
        } catch (ModelNotFoundException $e) {
            throw new BookmarkNotFoundException('Bookmark not found', 404);
        }
    }

    /**
     * Update an existing Bookmark.
     *
     * @param array $attributes
     * @param int $id
     *
     * @return bool
     */
    public function update(array $attributes, int $id): bool
    {
        try {
            return $this->find($id)->update($attributes);
        } catch (QueryException $e) {
            throw new UpdateBookmarkErrorException("Can't update", 400);
        }
    }

    /**
     * @param int $id
     *
     * @return bool|null
     */
    public function delete(int $id): ?bool
    {
        $bookmark = $this->model->find($id);

        if (!$bookmark) {
            return null;
        }

        return $bookmark->delete();
    }
}
